/**
 * 
 */
package com.volatileengine.renderer.lwjgl;

import java.nio.IntBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.ARBMultitexture;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GLContext;

import com.volatileengine.material.states.TextureRenderState;

/**
 * @author Ahmed
 * 
 */
public class LWJGLTextureRenderStateRenderer {
	private static int MAX_TEXTURE_UNITS = -1;

	public LWJGLTextureRenderStateRenderer() {
		if (MAX_TEXTURE_UNITS == -1) {
			IntBuffer buffer = BufferUtils.createIntBuffer(16);
			GL11.glGetInteger(ARBMultitexture.GL_MAX_TEXTURE_UNITS_ARB, buffer);
			MAX_TEXTURE_UNITS = buffer.get(0);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.volatileengine.renderer.renderatoms.RenderAtom#render(java.lang.
	 * Object)
	 */
	public void render(TextureRenderState object) {
		if (object == null) {
			return;
		}

		if (GLContext.getCapabilities().GL_ARB_multitexture) {
			// loop through the texture units and disable them
			for (int i = 0; i < MAX_TEXTURE_UNITS; i++) {
				ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE0_ARB + i);
				GL11.glEnable(GL11.GL_TEXTURE_2D);
			}
		} else {
			GL11.glEnable(GL11.GL_TEXTURE_2D);
		}
		// loop through the textures and enable multi texturing
		for (int i = 0; i < object.getTextures().length; i++) {
			if (GLContext.getCapabilities().GL_ARB_multitexture) {
				ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE0_ARB + i);
			}

			if (object.getTextures()[i] != null) {
				GL11.glBindTexture(GL11.GL_TEXTURE_2D, object.getTextures()[i].getHandle().getIdentity());
			}

			// if multi texturing isn't available, break
			if (GLContext.getCapabilities().GL_ARB_multitexture == false) {
				break;
			}
		}

		// loop through the remaining texture units and disable them for
		// this pass to avoid texture bleeding onto other passes or onto other
		// geometry
		for (int i = object.getTextures().length; i < MAX_TEXTURE_UNITS; i++) {
			// activate the channel
			if (GLContext.getCapabilities().GL_ARB_multitexture) {
				ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE0_ARB + i);
			}

			// disable the texture
			GL11.glDisable(GL11.GL_TEXTURE_2D);

			// if multi texturing isn't available, break
			if (GLContext.getCapabilities().GL_ARB_multitexture == false) {
				break;
			}
		}

		// disable stuff now
		if (GLContext.getCapabilities().GL_ARB_multitexture) {
			// loop through the texture units and disable them
			for (int i = 0; i < MAX_TEXTURE_UNITS; i++) {
				ARBMultitexture.glActiveTextureARB(ARBMultitexture.GL_TEXTURE0_ARB + i);
				GL11.glDisable(GL11.GL_TEXTURE_2D);
			}
		} else {
			GL11.glDisable(GL11.GL_TEXTURE_2D);
		}
	}
}
